﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace SequentialPattern.BasicClass
{
    /// <summary>
    /// 序列樣式集合
    /// </summary>
    [Serializable]
    public class SequentialPatternCollection : Collection<Pattern>
    {
        /// <summary>
        /// 將序列樣式集合存檔
        /// </summary>
        /// <param name="outputfile">檔案路徑</param>
        /// <param name="sequentialPatternCollection">儲存的序列樣式集合</param>
        /// <param name="format">儲存格式</param>
        public static void SaveTo(string outputfile, SequentialPatternCollection sequentialPatternCollection, SequentialPatternSaveFormat format)
        {
            switch (format)
            {
                case SequentialPatternSaveFormat.Text:
                    SaveToText(outputfile, sequentialPatternCollection);
                    break;
                case SequentialPatternSaveFormat.Xml:
                    SaveToXml(outputfile, sequentialPatternCollection);
                    break;
                case SequentialPatternSaveFormat.Binary:
                    SaveToBinary(outputfile, sequentialPatternCollection);
                    break;
            }
        }

        /// <summary>
        /// 從檔案讀取序列樣式集合
        /// </summary>
        /// <param name="intputfile">檔案路徑</param>
        /// <param name="format">讀取格式</param>
        /// <returns>序列樣式集合</returns>
        public static SequentialPatternCollection ReadFrom(string intputfile, SequentialPatternSaveFormat format)
        {
            SequentialPatternCollection result=new SequentialPatternCollection();
            switch (format)
            {
                case SequentialPatternSaveFormat.Text:
                    result = ReadFromText(intputfile);
                    break;
                case SequentialPatternSaveFormat.Xml:
                    result = ReadFromXml(intputfile);
                    break;
                case SequentialPatternSaveFormat.Binary:
                    result = ReadFromBinary(intputfile);
                    break;
            }
            return result;
        }

        /// <summary>
        /// 存成文字檔
        /// </summary>
        /// <param name="outputfile">檔案路徑</param>
        /// /// <param name="sequentialPatternCollection">儲存的序列樣式集合</param>
        private static void SaveToText(string outputfile, SequentialPatternCollection sequentialPatternCollection)
        {
            StreamWriter sw = new StreamWriter(outputfile);
            foreach (Pattern pattern in sequentialPatternCollection)
                sw.WriteLine(pattern.ToString());
            sw.Close();
        }

        /// <summary>
        /// 存成Binary檔
        /// </summary>
        /// <param name="outputfile">檔案路徑</param>
        /// <param name="sequentialPatternCollection">儲存的序列樣式集合</param>
        private static void SaveToBinary(string outputfile, SequentialPatternCollection sequentialPatternCollection)
        {
            IFormatter binFmt = new BinaryFormatter();
            Stream s = File.Open(outputfile, FileMode.Create);
            binFmt.Serialize(s, sequentialPatternCollection);
            s.Close();
        }

        /// <summary>
        /// 存成Xml檔
        /// </summary>
        /// <param name="outputfile">檔案路徑</param>
        /// <param name="sequentialPatternCollection">儲存的序列樣式集合</param>
        private static void SaveToXml(string outputfile, SequentialPatternCollection sequentialPatternCollection)
        {
            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(sequentialPatternCollection.GetType());
            Stream s = File.Open(outputfile, FileMode.Create);
            ser.Serialize(s, sequentialPatternCollection);
            s.Close();
        }

        /// <summary>
        /// 從文字檔讀取成序列樣式集合
        /// </summary>
        /// <param name="inpputfile">檔案路徑</param>
        /// <returns>序列樣式集合</returns>
        private static SequentialPatternCollection ReadFromText(string inpputfile)
        {
            throw new NotImplementedException("此方法尚未實作");
        }

        /// <summary>
        /// 從Binary讀取成序列樣式集合
        /// </summary>
        /// <param name="inputfile">檔案路徑</param>
        /// <returns>序列樣式集合</returns>
        private static SequentialPatternCollection ReadFromBinary(string inputfile)
        {
            SequentialPatternCollection result;
            IFormatter binFmt = new BinaryFormatter();
            Stream s = File.Open(inputfile, FileMode.Open);
            result = (SequentialPatternCollection)binFmt.Deserialize(s);
            s.Close();
            return result;
        }

        /// <summary>
        /// 從Xml讀取成序列樣式集合
        /// </summary>
        /// <param name="inputfile">檔案路徑</param>
        /// <returns>序列樣式集合</returns>
        private static SequentialPatternCollection ReadFromXml(string inputfile)
        {
            FileStream myFs = new FileStream(inputfile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            System.Xml.Serialization.XmlSerializer myXS = new System.Xml.Serialization.XmlSerializer(typeof(SequentialPatternCollection));
            SequentialPatternCollection result = (SequentialPatternCollection)myXS.Deserialize(myFs);
            myFs.Close();
            return result;
        }

        /// <summary>
        /// 取得序列樣式集合中長度為length的序列樣式
        /// </summary>
        /// <param name="length">輸入長度</param>
        /// <returns>長度為length的序列樣式</returns>
        public SequentialPatternCollection GetByLength(int length)
        {
            SequentialPatternCollection result = new SequentialPatternCollection();
            foreach (Pattern pattern in this)
                if (pattern.Length == length)
                    result.Add(pattern);
            return result;
        }        
    }

    /// <summary>
    /// 序列樣式集合存檔的格式
    /// </summary>
    public enum SequentialPatternSaveFormat
    {
        /// <summary>
        /// 純文字檔
        /// </summary>
        Text,
        /// <summary>
        /// 二進位檔
        /// </summary>
        Binary,
        /// <summary>
        /// XML檔
        /// </summary>
        Xml
    }
}
